package com.shuai.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuai.mapper.SysPermissionMapper;
import com.shuai.mapper.SysRolePermissionMapper;
import com.shuai.model.bo.AllotBo;
import com.shuai.model.converter.SysPermissionConverter;
import com.shuai.model.po.SysPermission;
import com.shuai.model.po.SysRolePermission;
import com.shuai.model.query.SysPermissionQuery;
import com.shuai.model.vo.SysPermissionVo;
import com.shuai.model.vo.SysRouterVO;
import com.shuai.service.SysPermissionService;
import com.shuai.utils.converter.PageConverter;
import com.shuai.utils.converter.SystemConverter;
import com.shuai.utils.data.DataUtil;
import com.shuai.utils.tree.SysTreeVo;
import com.shuai.utils.tree.TreeUtil;
import com.shuai.utils.tree.TreeUtils;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 权限信息 服务实现类
 *
 * @author shuai
 * @since 2022
 */
@Slf4j
@Service
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements SysPermissionService {

    @Resource
    private SysPermissionMapper sysPermissionMapper;

    @Resource
    private SysRolePermissionMapper sysRolePermissionMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addSysPermission(SysPermission sysPermission) {
        sysPermissionMapper.insert(sysPermission);
        //更新层级地址
        String labelPath = sysPermission.getLabelPath()+sysPermission.getId()+":";
        SysPermission permission = SysPermission.builder().id(sysPermission.getId()).labelPath(labelPath).build();
        return sysPermissionMapper.updateById(permission);
    }

    @Override
    public Integer deleteSysPermission(SysPermissionQuery query) {
        return sysPermissionMapper.deleteBatchIds(query.getIds());
    }

    @Override
    public Integer editSysPermission(SysPermission sysPermission) {
        return sysPermissionMapper.updateById(sysPermission);
    }

    @Override
    public List<SysPermissionVo> selectList(SysPermissionQuery query) {
        QueryWrapper<SysPermission> queryWrapper = new QueryWrapper();
        fillQueryWrapper(queryWrapper, query);
        List<SysPermission> permissionList = sysPermissionMapper.selectList(queryWrapper);
        return SysPermissionConverter.convertToVoByPo(permissionList);
    }

    @Override
    public IPage<SysPermissionVo> selectPage(SysPermissionQuery query) {
        QueryWrapper<SysPermission> queryWrapper = new QueryWrapper();
        fillQueryWrapper(queryWrapper, query);
        Page<SysPermission> page = new Page<>(query.getPage(), query.getLimit());
        IPage<SysPermission> pageList = sysPermissionMapper.selectPage(page, queryWrapper);
        List<SysPermissionVo> records = SysPermissionConverter.convertToVoByPo(pageList.getRecords());
        return PageConverter.convertToPage(pageList, records);
    }

    @Override
    public SysPermissionVo selectById(Long id) {
        SysPermission permission = sysPermissionMapper.selectById(id);
        return SysPermissionConverter.convertToVoByPo(permission);
    }

    @Override
    public List<SysRouterVO> getUserMenuInfo(List<Long> roles) {
        //通过角色id获取权限id
        LambdaQueryWrapper<SysRolePermission> roleWrapper = Wrappers.lambdaQuery();
        roleWrapper.in(ObjectUtil.isNotEmpty(roles), SysRolePermission::getRoleId, roles);
        Set<Long> permissionIds = sysRolePermissionMapper.selectList(roleWrapper).stream().map(SysRolePermission::getPermissionId).collect(Collectors.toSet());
        //获取权限
        List<SysPermission> list = sysPermissionMapper.selectBatchIds(permissionIds);
        list = list.stream().filter(f -> f.getType() != 2).collect(Collectors.toList());
        List<SysRouterVO> menuVoList = TreeUtils.makeRouter(list, "#");
        return menuVoList;
    }

    @Override
    public List<SysPermissionVo> selectTreeList(SysPermissionQuery query) {
        QueryWrapper<SysPermission> queryWrapper = new QueryWrapper();
        fillQueryWrapper(queryWrapper, query);
        List<SysPermission> list = sysPermissionMapper.selectList(queryWrapper);

        if(StrUtil.isNotEmpty(query.getLabelLike())){
            List<SysPermission> newList = sysPermissionMapper.selectList(new QueryWrapper<>());
            Set<SysPermission> set = CollUtil.newHashSet();
            list.stream().forEach(item ->{
                //获取层级中包含id的数据
                List<String> ids = Stream.of(item.getLabelPath().split(":")).collect(Collectors.toList());
                ids.stream().forEach(id->{
                    set.addAll(newList.stream().filter(t ->String.valueOf(t.getId()).equals(id)).collect(Collectors.toList()));
                });
                set.addAll(newList.stream().filter(t ->t.getLabelPath().contains(String.valueOf(item.getId()))).collect(Collectors.toList()));
            });
            list = Lists.newArrayList();
            list.addAll(set);
        }

        List<SysPermissionVo> permissionList = TreeUtil.makeTreeForAny(SysPermissionConverter.convertToVoByPo(list), "#");
        return permissionList;
    }

    @Override
    public List<SysTreeVo> selectPermissionTree(SysPermissionQuery query) {
        LambdaQueryWrapper<SysPermission> wrapper = Wrappers.lambdaQuery();
        wrapper.ne(SysPermission::getType,2);
        List<SysPermission> list = sysPermissionMapper.selectList(wrapper);

        List<SysTreeVo> treeVoList = TreeUtil.makeTreeForSysTree(SystemConverter.convertToVoByPo(list), "#");
        return treeVoList;
    }

    @Override
    public AllotBo selectRolePermissionList(Long roleId) {
        //获取所有权限
        List<SysPermission> permissionList = sysPermissionMapper.selectList(new QueryWrapper<>());
        List<SysTreeVo> treeVoList = TreeUtil.makeTreeForSysTree(SystemConverter.convertToVoByPo(permissionList), "#");
        //获取已存在的权限Id
        LambdaQueryWrapper<SysRolePermission> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ObjectUtil.isNotEmpty(roleId),SysRolePermission::getRoleId,roleId);
        List<String> ids = sysRolePermissionMapper.selectList(wrapper).stream()
                .map(SysRolePermission::getPermissionId).map(String::valueOf).collect(Collectors.toList());
        return AllotBo.builder().treeData(treeVoList).checkDataId(ids).build();
    }


    /**
     * 生成查询条件与排序
     *
     * @param query
     * @return
     */
    private void fillQueryWrapper(QueryWrapper<SysPermission> queryWrapper, SysPermissionQuery query) {
        //组织查询条件
        queryWrapper.lambda()
                .like(StrUtil.isNotEmpty(query.getLabelLike()), SysPermission::getLabel, query.getLabelLike())
        ;

        //生成order by 的语句
        DataUtil.fillOrderBy(query, queryWrapper, SysPermission.class);
    }
}
